#include "GapGenerator.h"
#include "GapStateMap.h"
#include "GapGlobals.h"
#include "MgwGapProxy.h"

namespace tsc
{
namespace sgw
{

using namespace tsc::common;

uint32_t GapGenerator::msGeneratorId = 0;

/*******************************************************************************
 *
 * Constructor
 *
 ******************************************************************************/
GapGenerator::GapGenerator(
		GeneratorEnvironment& ge,
		uint32_t mgwId) :
	Generator(ge, GapStateMap::instance().initialState()),
	mpT823(0),
	mpT8221(0),
	mpMgwIpAddress(0)
{
    if(mgwId == GAP_MGW_INITIAL_ID)
    {
        assignGeneratorId();
    }
    else
    {
        _generatorId = mgwId;
    }

    mpT8221 = new Timer(
            MgwGapProxy::instance().getRequestHandler(),
            getMgwId(),
            GAP_TIMER_ID_T8221,
            TIMER_TYPE_GAP);

    mpT823 = new Timer(
            MgwGapProxy::instance().getRequestHandler(),
            getMgwId(),
            GAP_TIMER_ID_T823,
            TIMER_TYPE_GAP);

    gGapGeneratorMap().insert(
			std::pair<uint32_t, GapGenerator*>(_generatorId, this));
} // GapGenerator::GapGenerator

/*******************************************************************************
 *
 * Destructor
 *
 ******************************************************************************/
GapGenerator::~GapGenerator()
{
    gGapGeneratorMap().erase(this->getMgwId());

    MgwGapProxy::instance().clearConnIdMapping(getMgwId());

	delete mpMgwIpAddress;
}

//===================================================================
void
GapGenerator::assignGeneratorId()
{
    uint32_t id = ++msGeneratorId;

    GapGenerator* dummyPointer;
    while(findGenerator(id, dummyPointer)){
        ++id;
    }
    _generatorId = id;
}

//===================================================================
bool
GapGenerator::txEnabled() const
{
    return static_cast<GapStateBase*>(_currentState)->txEnabled();
}

//===================================================================
bool
GapGenerator::findGenerator(uint32_t mgwId, GapGenerator*& generator)
{
	std::map<uint32_t, GapGenerator*>::iterator it =
	        gGapGeneratorMap().find(mgwId);
	if(it != gGapGeneratorMap().end())
	{
		generator = it->second;
		return true;
	}
	return false;
}


uint32_t
GapGenerator::getMgwId() const
{
    // MGW ID is equal to generator ID
    return _generatorId;
}

void
GapGenerator::startT823(unsigned long valueMs)
{

    mpT823->start(valueMs);
}

void
GapGenerator::cancelT823()
{
    mpT823->cancel();
}

void
GapGenerator::startT8221(unsigned long valueMs)
{
    mpT8221->start(valueMs);
}

void
GapGenerator::cancelT8221()
{
    mpT8221->cancel();
}

const ProtocolsCommon::IpAddress*
GapGenerator::getMgwIpAddress() const
{
    return mpMgwIpAddress;
}

void
GapGenerator::setMgwIpAddress(
    ProtocolsCommon::IpAddress* mgwIpAddress)
{
    if(this->mpMgwIpAddress)
    {
        delete this->mpMgwIpAddress;
    }
    this->mpMgwIpAddress = new ProtocolsCommon::IpAddress(*mgwIpAddress);
}



} // namespace sgw
} // namespace tsc
